/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bot_jae;

import ai_util.LogFile;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;

/**
 *
 * @author John, Ashley, Eric
 * Based on bot_Hippo
 * 
 */
public class Bot_jae {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        
        LogFile.setMessageDisplay(false);
	LogFile.message((new Date()).toString());
        
        Bot_jae main = new Bot_jae();
	main.control();
        
    }
    
    public Bot_jae() {
	}

	private EngineThread engine_thread = new EngineThread();
	private ServerInfo info = new ServerInfo();

	// All messages must by sent thru here so they get logged
	private static void send_message(String text) {
		text += "\n";
		ai_util.LogFile.message("AEI s --> " + text);
		System.out.print(text);
		System.out.flush();
	}

	public static void chat(String msg) {
		send_message("chat "+msg);
	}
	
	private void control() {
            
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				System.in));
            
		while (true) {
                    
			try {
                            
				// Get the message
				String message = reader.readLine();

				// Write message to log file
				ai_util.LogFile.message("AEI r--> " + message);

				// If connection broken, just shutdown
				if (message == null) {
					//info.engine.shutdown_search();
					return;
				}

                                AEICommand AEIcommand = new AEICommand(message);

				// Figure out which command it is
				if (AEIcommand.command.equals("aei")) {
					send_message("protocol version 1");
					send_message("id name jae");
					send_message("id author John-Ashley-Eric");
					send_message("id version 2012");
					send_message("aeiok");
                                }

				else if (AEIcommand.command.equals("isready")) {
					send_message("readyok");
				}

				else if (AEIcommand.command.equals("quit")) {
					info.engine.abort_search();
					return;
				}

				else if (AEIcommand.command.equals("stop")) {
					info.engine.abort_search();
				}

				else if (AEIcommand.command.equals("newgame")) {
					info.engine.abort_search();
					send_message("log starting new game");
					info.newGame();
                                        System.out.println("did new game?");
				}

				else if (AEIcommand.command.equals("makemove")) {
					String move_text = AEIcommand.getRestOfCommand();
					info.board.makeMove(move_text);
				//	info.ShrinkRules();
				}

				else if (AEIcommand.command.equals("chat")) {
					String chatMessage = AEIcommand.getRestOfCommand();
					info.chat(chatMessage);
				}
/* just for game analysis
				else if (AEIcommand.command.equals("setposition")) {
					String position_text = AEIcommand.getRestOfCommand();
					info.newStartPosition(position_text);
				}
*/
				else if (AEIcommand.command.equals("setoption")) {
					String name = AEIcommand.arguments[2];
					String value = AEIcommand.arguments[4];
					set_option(name, value);
				}

				else if (AEIcommand.command.equals("go")) {
					if (AEIcommand.getRestOfCommand().equals("ponder")) {
						// info.ShrinkRules();
					} else {
						send_message("log starting search");
						engine_thread.run();
					}
				}

				// Try sending command on to the engine
				else {
					// Unknown command received, just log it and ignore the
					// command
				}

			} // Loop forever

			// This should never happen!
			// We're sunk if we get here, just exit
			catch (Exception e) {
				StringWriter sw = new StringWriter();
				e.printStackTrace(new PrintWriter(sw));
				String stackTrace = sw.toString();
				ai_util.LogFile.message("Exception " + e);
				ai_util.LogFile.message(stackTrace);
			}
		}
	}

	private void set_option(String name, String value_text) {
		name = name.toLowerCase();
		ai_util.LogFile.message("set option "+name+":"+value_text);
		if (name.equals("rated")) {
			info.is_rated = value_text.equals("1") ? true : false;
		} else if (name.equals("hash")) {
			info.allowed_hash_size = Integer.parseInt(value_text);
		} else if (name.equals("opponent")) {
			info.enemy_name = value_text;
		} else if (name.equals("tcmove")) {
			int value = Integer.parseInt(value_text);
			info.tc_move = value;
		} else if (name.equals("tcpercent")) {
			int value = Integer.parseInt(value_text);
			info.tc_percent = value;
		} else if (name.equals("tcmax")) {
			int value = Integer.parseInt(value_text);
			if (value == 0) {
				value = Integer.MAX_VALUE;
			}
			info.tc_max_reserve = value;
		} else if (name.equals("tcreserve")) {
			int value = Integer.parseInt(value_text);
			info.tc_reserve[0] = info.tc_reserve[1] = value;
		} else if (name.equals("tcturns")) {
			int value = Integer.parseInt(value_text);
			info.tc_turns = value;
		} else if (name.equals("rating")) {
			int value = Integer.parseInt(value_text);
			info.rating = value;
		} else if (name.equals("opponent_rating")) {
			int value = Integer.parseInt(value_text);
			info.opponent_rating = value;
		} else if (name.equals("tctotal")) {
			int value = Integer.parseInt(value_text);
			info.tc_total = value;
		} else if (name.equals("wused")) {
			//int value = Integer.parseInt(value_text);
			//info.used[0] = value;
		} else if (name.equals("bused")) {
			//int value = Integer.parseInt(value_text);
			//info.used[1] = value;
		} else if (name.equals("tclastmoveused")) {
			//int value = Integer.parseInt(value_text);
			//info.used[0] = value;
		} else if (name.equals("lastmoveused")) {
			//int value = Integer.parseInt(value_text);
			//info.used[0] = value;
		} else if (name.equals("moveused")) {
			int value = Integer.parseInt(value_text);
			info.moveused = value;
		} else if (name.equals("tcmoveused")) {
			int value = Integer.parseInt(value_text);
			info.tc_moveused = value;
		} else if (name.equals("tcturntime")) {
			int value = Integer.parseInt(value_text);
			if (value == 0) {
				value = Integer.MAX_VALUE;
			}
			info.tc_max_turn_time = value;
		} else if (name.equals("wreserve")) {
			int value = Integer.parseInt(value_text);
			info.tc_reserve[0] = value;
		} else if (name.equals("breserve")) {
			int value = Integer.parseInt(value_text);
			info.tc_reserve[1] = value;
		} else {
			ai_util.LogFile.message("unknown info "+name);
		}
	}

	// Separate thread to run the engine
	private class EngineThread implements Runnable {
		public void run() {
			long start_time = System.currentTimeMillis();

//                        MoveInfo move = info.engine.genMove(info);
//			String final_move = move.move_text.replaceAll(" pass", "");
                        String final_move = info.engine.genMove(info);
			send_message("bestmove " + final_move);

			long elapsed_time = System.currentTimeMillis() - start_time;
			ai_util.LogFile.message("Elapsed time: " + elapsed_time + " ms");
		}
	}
}
